package shaman.storage.impl.util;

import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Iterator;
import shaman.storage.impl.file.IterationException;

public class ObjectStreamIterator<T> implements Iterator<T> {

    private T cur;
    private boolean eof;
    private ObjectInputStream oi;
    private Class<? extends T> ocl;

    public ObjectStreamIterator(ObjectInputStream oi, Class<? extends T> ocl) throws IterationException {
        this.oi = oi;
        this.ocl = ocl;
        seekNext();
    }

    public boolean hasNext() throws IterationException {
        return cur != null;
    }

    public T next() {
        T ret = cur;
        if (ret != null) {
            seekNext();
        }
        return ret;
    }

    public void remove() {
        throw new UnsupportedOperationException("Not possible with this type of iterator");
    }

    private void seekNext() throws IterationException {
        cur = null;
        if (eof) {
            return;
        }
        do {
            Object obj;
            try {
                obj = oi.readObject();
            } catch (ClassNotFoundException ex) {
                continue;
            } catch (EOFException ex) {
                eof = true;
                try {
                    oi.close();
                } catch (IOException exx) {
                }
                oi = null;
                break;
            } catch (IOException ex) {
                throw new IterationException("Unable to get next element", ex);
            }
            if (obj != null) {
                if (!(ocl.isAssignableFrom(obj.getClass()))) {
                    continue;
                }
                cur = (T) obj;
            }
        } while (cur == null);
    }
}
